package com.twb.core.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.X509TrustManager;

import com.alibaba.fastjson.JSONObject;

/** 
 * @ClassName HttpUtil 
 * @Description http工具类
 * @author DSY
 * @date 2018年12月11日 下午4:18:03 
 */ 
public class HttpUtil {
	private static String charset = "utf-8";
	private static String proxyHost = null;
	private static Integer proxyPort = null;
	/**
     * Https请求
     */
    private static final String HTTPS = "https";
	/**
	 * @Title  doGet
	 * @Class: HttpUtil.java
	 * @Package: com.dths.sw.core.wms.util
	 * @Description GET 请求，不含参数
	 * @param url
	 * @return
	 * @throws Exception
	 * @author DSY
	 * @date 2018年12月11日 下午4:18:16
	 */
	public static String doGet(String url) throws Exception {
		return doGet(url, null);
	}
	
	/**
	 * @Title  doGet
	 * @Class: HttpUtil.java
	 * @Package: com.dths.sw.core.wms.util
	 * @Description GET 请求，可传递参数
	 * @param url
	 * @param parameterMap
	 * @return
	 * @throws Exception
	 * @author DSY
	 * @date 2018年12月11日 下午4:18:29
	 */
	public static String doGet(String url, Map<String,String> parameterMap) throws Exception {
		return doGet(url, null, parameterMap);
	}
	/**
	 * @Title  doGet
	 * @Class: HttpUtil.java
	 * @Package: com.dths.sw.core.wms.util
	 * @Description GET 请求，可传递header参数和普通参数
	 * @param url
	 * @param headerParameterMap
	 * @param parameterMap
	 * @return
	 * @throws Exception
	 * @author DSY
	 * @date 2018年12月11日 下午4:18:43
	 */
	public static String doGet(String url, Map<String,String> headerParameterMap, Map<String,String> parameterMap) throws Exception {

		/* Translate parameter map to parameter date string */
		StringBuffer parameterBuffer = new StringBuffer();
		if (parameterMap != null) {
			Iterator<String> iterator = parameterMap.keySet().iterator();
			String key = null;
			String value = null;
			while (iterator.hasNext()) {
				key = iterator.next();
				if (parameterMap.get(key) != null) {
					value = parameterMap.get(key);
				} else {
					value = "";
				}

				parameterBuffer.append(key).append("=").append(value);
				if (iterator.hasNext()) {
					parameterBuffer.append("&");
				}
			}
			if(!parameterMap.isEmpty()) {
				url = url+"?"+parameterBuffer.toString();
			}
		}
		System.out.println("GET parameter : " + parameterBuffer.toString());
		// 如果是Https请求
        if (url.startsWith(HTTPS)) {
            getTrust();
        }
		URL localURL = new URL(url);

		URLConnection connection = openConnection(localURL);
		HttpURLConnection httpURLConnection = (HttpURLConnection) connection;

		httpURLConnection.setRequestProperty("Accept-Charset", charset);
		httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

		if(headerParameterMap != null) {
			Iterator<String> iterator = headerParameterMap.keySet().iterator();
			String key = null;
			String value = null;
			while (iterator.hasNext()) {
				key = iterator.next();
				if (headerParameterMap.get(key) != null) {
					value = headerParameterMap.get(key);
					httpURLConnection.setRequestProperty(key, value);
				}
			}
		}
		
		InputStream inputStream = null;
		InputStreamReader inputStreamReader = null;
		BufferedReader reader = null;
		StringBuffer resultBuffer = new StringBuffer();
		String tempLine = null;

		if (httpURLConnection.getResponseCode() >= 300) {
			throw new Exception("HTTP Request is not success, Response code is " + httpURLConnection.getResponseCode());
		}

		try {
			inputStream = httpURLConnection.getInputStream();
			inputStreamReader = new InputStreamReader(inputStream,charset);
			reader = new BufferedReader(inputStreamReader);

			while ((tempLine = reader.readLine()) != null) {
				resultBuffer.append(tempLine);
			}

		} finally {

			if (reader != null) {
				reader.close();
			}

			if (inputStreamReader != null) {
				inputStreamReader.close();
			}

			if (inputStream != null) {
				inputStream.close();
			}

		}

		return resultBuffer.toString();
	}

	
	/**
	 * @Title  doPost
	 * @Class: HttpUtil.java
	 * @Package: com.dths.sw.core.wms.util
	 * @Description POST 请求，不含参数
	 * @param url
	 * @return
	 * @throws Exception
	 * @author DSY
	 * @date 2018年12月11日 下午4:19:03
	 */
	public static String doPost(String url) throws Exception {
		Map<String,String> parameterMap = new HashMap<String,String>();
		return doPost(url, parameterMap);
	}
	
	/**
	 * @Title  doPost
	 * @Class: HttpUtil.java
	 * @Package: com.dths.sw.core.wms.util
	 * @Description POST请求，可传递参数
	 * @param url
	 * @param parameterMap
	 * @return
	 * @throws Exception
	 * @author DSY
	 * @date 2018年12月11日 下午4:19:14
	 */
	public static String doPost(String url, Map<String,String> parameterMap) throws Exception {
		return doPost(url, null, parameterMap);
	}
	/**
	 * @Title  doPost
	 * @Class: HttpUtil.java
	 * @Package: com.dths.sw.core.wms.util
	 * @Description POST请求，可传递header参数和普通参数
	 * @param url
	 * @param headerParameterMap
	 * @param parameterMap
	 * @return
	 * @throws Exception
	 * @author DSY
	 * @date 2018年12月11日 下午4:19:28
	 */
	public static String doPost(String url, Map<String,String> headerParameterMap, Map<String,String> parameterMap) throws Exception {

		/* Translate parameter map to parameter date string */
		StringBuffer parameterBuffer = new StringBuffer();
		JSONObject jsonObject = new JSONObject();
		if (parameterMap != null) {
			Iterator<String> iterator = parameterMap.keySet().iterator();
			String key = null;
			String value = null;
			while (iterator.hasNext()) {
				key = iterator.next();
				if (parameterMap.get(key) != null) {
					value = parameterMap.get(key);
				} else {
					value = "";
				}
				jsonObject.put(key, value);
				parameterBuffer.append(key).append("=").append(value);
				if (iterator.hasNext()) {
					parameterBuffer.append("&");
				}
			}
		}
		
		JSONObject bodyJsonObject = new JSONObject();
		bodyJsonObject.put("body", jsonObject);
		System.out.println("POST parameter : " + bodyJsonObject.toJSONString());

		// 如果是Https请求
        if (url.startsWith(HTTPS)) {
            getTrust();
        }
        
		URL localURL = new URL(url);

		URLConnection connection = openConnection(localURL);
		HttpURLConnection httpURLConnection = (HttpURLConnection) connection;

		httpURLConnection.setDoOutput(true);
		httpURLConnection.setRequestMethod("POST");
		httpURLConnection.setRequestProperty("Accept-Charset", charset);
		httpURLConnection.setRequestProperty("Content-Type", "application/json");
		httpURLConnection.setRequestProperty("Content-Length", String.valueOf(parameterBuffer.length()));

		if(headerParameterMap != null) {
			Iterator<String> iterator = headerParameterMap.keySet().iterator();
			String key = null;
			String value = null;
			while (iterator.hasNext()) {
				key = iterator.next();
				if (headerParameterMap.get(key) != null) {
					value = headerParameterMap.get(key);
					httpURLConnection.setRequestProperty(key, value);
				}
			}
		}
		
		OutputStream outputStream = null;
		OutputStreamWriter outputStreamWriter = null;
		InputStream inputStream = null;
		InputStreamReader inputStreamReader = null;
		BufferedReader reader = null;
		StringBuffer resultBuffer = new StringBuffer();
		String tempLine = null;

		try {
			outputStream = httpURLConnection.getOutputStream();
			outputStreamWriter = new OutputStreamWriter(outputStream);

			outputStreamWriter.write(bodyJsonObject.toJSONString());
			outputStreamWriter.flush();

			if (httpURLConnection.getResponseCode() >= 300) {
				throw new Exception(
						"HTTP Request is not success, Response code is " + httpURLConnection.getResponseCode());
			}

			inputStream = httpURLConnection.getInputStream();
			inputStreamReader = new InputStreamReader(inputStream,charset);
			reader = new BufferedReader(inputStreamReader);

			while ((tempLine = reader.readLine()) != null) {
				resultBuffer.append(tempLine);
			}

		} finally {

			if (outputStreamWriter != null) {
				outputStreamWriter.close();
			}

			if (outputStream != null) {
				outputStream.close();
			}

			if (reader != null) {
				reader.close();
			}

			if (inputStreamReader != null) {
				inputStreamReader.close();
			}

			if (inputStream != null) {
				inputStream.close();
			}

		}

		return resultBuffer.toString();
	}

	/**
	 * @Title  doPost
	 * @Class: HttpUtil.java
	 * @Package: com.dths.sw.core.util
	 * @Description 
	 * @param url
	 * @param paramJson
	 * @return
	 * @throws Exception
	 * @author DSY
	 * @date 2018年12月12日 上午9:54:04
	 */
	public static String doPost(String url, JSONObject paramJson) throws Exception {
		return doPost(url, null, paramJson);
	}
	
	/**
	 * @Title  doPost
	 * @Class: HttpUtil.java
	 * @Package: com.dths.sw.core.util
	 * @Description POST请求，传递json参数
	 * @param url
	 * @param headerParameterMap
	 * @param paramJson
	 * @return
	 * @throws Exception
	 * @author DSY
	 * @date 2018年12月12日 上午9:53:22
	 */
	public static String doPost(String url, Map<String,String> headerParameterMap, JSONObject paramJson) throws Exception {

		/* Translate parameter map to parameter date string */
		StringBuffer parameterBuffer = new StringBuffer();
		
		System.out.println("POST parameter : " + paramJson.toJSONString());

		// 如果是Https请求
        if (url.startsWith(HTTPS)) {
            getTrust();
        }
        
		URL localURL = new URL(url);

		URLConnection connection = openConnection(localURL);
		HttpURLConnection httpURLConnection = (HttpURLConnection) connection;

		httpURLConnection.setDoOutput(true);
		httpURLConnection.setRequestMethod("POST");
		httpURLConnection.setRequestProperty("Accept-Charset", charset);
		httpURLConnection.setRequestProperty("Content-Type", "application/json");
		httpURLConnection.setRequestProperty("Content-Length", String.valueOf(parameterBuffer.length()));

		if(headerParameterMap != null) {
			Iterator<String> iterator = headerParameterMap.keySet().iterator();
			String key = null;
			String value = null;
			while (iterator.hasNext()) {
				key = iterator.next();
				if (headerParameterMap.get(key) != null) {
					value = headerParameterMap.get(key);
					httpURLConnection.setRequestProperty(key, value);
				}
			}
		}
		
		OutputStream outputStream = null;
		OutputStreamWriter outputStreamWriter = null;
		InputStream inputStream = null;
		InputStreamReader inputStreamReader = null;
		BufferedReader reader = null;
		StringBuffer resultBuffer = new StringBuffer();
		String tempLine = null;

		try {
			outputStream = httpURLConnection.getOutputStream();
			outputStreamWriter = new OutputStreamWriter(outputStream);

			outputStreamWriter.write(paramJson.toJSONString());
			outputStreamWriter.flush();

			if (httpURLConnection.getResponseCode() >= 300) {
				throw new Exception(
						"HTTP Request is not success, Response code is " + httpURLConnection.getResponseCode());
			}

			inputStream = httpURLConnection.getInputStream();
			inputStreamReader = new InputStreamReader(inputStream,charset);
			reader = new BufferedReader(inputStreamReader);

			while ((tempLine = reader.readLine()) != null) {
				resultBuffer.append(tempLine);
			}

		} finally {

			if (outputStreamWriter != null) {
				outputStreamWriter.close();
			}

			if (outputStream != null) {
				outputStream.close();
			}

			if (reader != null) {
				reader.close();
			}

			if (inputStreamReader != null) {
				inputStreamReader.close();
			}

			if (inputStream != null) {
				inputStream.close();
			}

		}

		return resultBuffer.toString();
	}
	private static URLConnection openConnection(URL localURL) throws IOException {
		URLConnection connection;
		if (proxyHost != null && proxyPort != null) {
			Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
			connection = localURL.openConnection(proxy);
		} else {
			connection = localURL.openConnection();
		}
		return connection;
	}
	
	/**
     * 获取服务器信任
     */
	private static void getTrust() {
		try {
			HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {

				public boolean verify(String hostname, SSLSession session) {
					return true;
				}
			});
			SSLContext context = SSLContext.getInstance("SSL");
			context.init(null, new X509TrustManager[] { new X509TrustManager() {

				public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
					return;
				}

				public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
					return;
				}

				public X509Certificate[] getAcceptedIssuers() {
					return null;
				}
			} }, new SecureRandom());
			HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}